#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <nice2d/application.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/linecontrol.h>
#include <nice2d/background.h>

IMPLEMENT_OBJECT(LineControlStyle, ControlStyle)

LineControlStyle::LineControlStyle()
{
    normalBackground = Background::create(sf::Color(128, 128, 128));
    hoverBackground = normalBackground;
    lineColor = sf::Color::White;
}

LineControlStyle::~LineControlStyle()
{
}

IMPLEMENT_OBJECT(LineControl, Control)

class LineControlData
{
public:
    LineControl *data = nullptr;

    sf::RectangleShape lineShape;
    Orientation orientation = Orientation_H;
    int lineWidth = 1;
    int middleLineWidth = 0;

    LineControlData(LineControl *thisControl):
        data(thisControl)
    {
        auto desktop = GET_APPLICATION_COMPONENT(Desktop);
        data->setControlStyle(desktop->getControlStyle("LineControl"));
    }
};

LineControl::LineControl():
    data(new LineControlData(this))
{
}

LineControl::~LineControl()
{
}

void LineControl::setOrientation(Orientation orientation)
{
    data->orientation = orientation;
    onUpdateControl(0.0f);

    if (data->orientation == Orientation_H)
        setHeight(3.0f);
    else
        setWidth(3.0f);
}

Orientation LineControl::getOrientation() const
{
    return data->orientation;
}

void LineControl::setLineWidth(int width)
{
    data->lineWidth = width;
    onUpdateControl(0.0f);
}

int LineControl::getLineWidth() const
{
    return data->lineWidth;
}

void LineControl::onUpdateControl(float deltaTime)
{
    int width, height;
    if (data->orientation == Orientation_H) {
        width = getSize().x * 0.8;
        height = data->lineWidth;
        setVResizeRule(ControlResizeRule_Fixed);
    } else {
        width = data->lineWidth;
        height = getSize().y * 0.8;
        setHResizeRule(ControlResizeRule_Fixed);
    }

    sf::Vector2f size(width, height);
    data->lineShape.setSize(size);

    sf::FloatRect area = getBoundingBox();
    auto pos = Entity::adjustPosition(area, size, HMode_Center, VMode_Center);

    data->lineShape.setPosition(pos - sf::Vector2f(area.left, area.top));
}

void LineControl::onDrawControl(sf::RenderTarget &target, sf::RenderStates states) const
{
    target.draw(data->lineShape, states);
}

void LineControl::onStyleChanged()
{
    Control::onStyleChanged();
    auto style = getTemplateStyle<LineControlStyle>();
    data->lineShape.setFillColor(style->lineColor);
}
